package org.nanotek.poi.writer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.lucene.analysis.pattern.PatternTokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.nanotek.base.ATContactBase;
import org.nanotek.base.NormalizedContact;
import org.nanotek.hibernate.dao.DAO;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ContactWriter {
	private static ClassPathXmlApplicationContext ctx;

	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, IOException, InvocationTargetException, NoSuchMethodException {
		ctx = new ClassPathXmlApplicationContext(new String[] {
				"database-loaders/spring-dao-context.xml"});
		
		ContactWriter writer = new ContactWriter();
		writer.write(ctx);
	}

	@SuppressWarnings("unchecked")
	private void write(ClassPathXmlApplicationContext ctx2) throws IllegalArgumentException, IllegalAccessException, IOException, InvocationTargetException, NoSuchMethodException {
		DAO<NormalizedContact> ndao = (DAO<NormalizedContact>) ctx.getBean("normalizedContactDAO");
		
		DAO<ATContactBase> atdao = (DAO<ATContactBase>) ctx.getBean("atContactBaseDAO");
		
		List<NormalizedContact> contacts = ndao.loadAll();
		
		for (NormalizedContact contact : contacts) 
		{ 
			ATContactBase base = new ATContactBase(); 
			base.setContactId(contact.getId());
			base.setCompanyName(contact.getNormalizedName());
			base.setAddress(contact.getNormalizedAddress());
			base.setBusinessPhone(contact.getNormalizedPhone());
			base.setAreaCode(contact.getPhoneAreaCode());
			base.setBusinessCity(contact.getCity());
			base.setBusinessPostalCode(contact.getZip());
			base.setBusinessState(contact.getState());
			base.setOtherPhone(contact.getPhone());
			base.setBusinessFax(contact.getMail());
			base.setDiscriminator("import1");
			atdao.update(base);
		}
		Workbook wb = prepareReport();
		Sheet sheet = wb.createSheet();
		prepareSheet(sheet); 
		exportBaseExcel(atdao,sheet);
		File file = new File("/home/java-eclipse/export-at-contactbase.xls");
		if (file.exists()) 
			file.delete(); 
		file.createNewFile();
		FileOutputStream out = new FileOutputStream(file);
		wb.write(out);
		out.close();
		ctx.close();
	}

	private void exportBaseExcel(DAO<ATContactBase> atdao , Sheet sheet) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException {
		
		List<ATContactBase> contacts = atdao.loadAll();
		
		int rownum =1; 
		BeanUtilsBean ub = BeanUtilsBean.getInstance();
		for (ATContactBase contact : contacts) 
		{   	
			Row row = sheet.createRow(rownum);
			Field[] fields = ATContactBase.class.getDeclaredFields();
			if (contact.getAreaCode() !=null && contact.getAreaCode().trim().length()>2)
				contact.setAreaCode(contact.getAreaCode().substring(0,2));
			List<String> result = null;
			if (contact.getOtherPhone() !=null) { 
				result = tokenizeByPattern(contact.getOtherPhone(), "/");
			} 
			
			if (result!=null&& result.size()>=2) 
				contact.setBusinessPhone2(result.get(1));

			result = null;
			if (contact.getAddress() !=null) 
				contact.setBussinessStreet(contact.getAddress());
			
			if (contact.getBusinessFax() !=null) { 
				result = tokenizeByPattern(contact.getOtherPhone(), "/");
			} 
			if (result!=null&&result.size()>=2) 
				contact.setBusinessFax2(result.get(1));
			
			int increment = 0;
			for (Field field : fields)
			{ 
				String value = ub.getProperty(contact, field.getName());
				Cell cell = row.createCell(increment);
				cell.setCellValue((value!=null)?value:"");
//				/System.out.println(field.getName());
				increment++;
			}
		
			rownum++;
		}
		
	}
	
	private Workbook prepareReport() {

		Workbook wb = new HSSFWorkbook();
		// create a new sheet
		return wb;
	}
	
	private void prepareSheet(Sheet sheet) {
		
		Row row = sheet.createRow(0);
		Field[] fields = ATContactBase.class.getDeclaredFields();
		int increment = 0;
		for (Field field : fields)
		{ 
			Cell cell = row.createCell(increment);
			cell.setCellValue(field.getName().toUpperCase());
			increment++;
//			/System.out.println(field.getName());
		}
		
//		Row row = sheet.createRow(0);
//		Cell cell = row.createCell(0);
//		cell.setCellValue("name".toUpperCase());
//		cell = row.createCell(1);
//		cell.setCellValue("address".toUpperCase());
//		cell = row.createCell(2);
//		cell.setCellValue("city".toUpperCase());
//		cell = row.createCell(3);
//		cell.setCellValue("state".toUpperCase());
//		cell = row.createCell(4);
//		cell.setCellValue("zip".toUpperCase());
//		cell = row.createCell(5);
//		cell.setCellValue("phone".toUpperCase());
//		cell = row.createCell(6);
//		cell.setCellValue("mail".toUpperCase());
	}
	
	private List<String> tokenizeByPattern(String value,String pattern) throws IOException {
		Pattern pat = Pattern.compile(pattern);
		StringReader reader = new StringReader(value);
		PatternTokenizer tokenizer = new PatternTokenizer(reader , pat, -1);
		tokenizer.reset();
		List<String> tokenString = new ArrayList<String>();

		while (tokenizer.incrementToken())
		{ 
			CharTermAttribute charTermAttribute =
					tokenizer.addAttribute(CharTermAttribute.class);
			tokenString.add(charTermAttribute.toString());
			//			System.out.println(charTermAttribute.toString());
		}
		tokenizer.close();
		return tokenString;
	}
}

